package com.cnpc.framework.base.service.impl;

import com.cnpc.framework.base.entity.BaseResponse;
import com.cnpc.framework.base.entity.SysFile;
import com.cnpc.framework.base.entity.UserAvatar;
import com.cnpc.framework.base.service.UploaderService;
import com.cnpc.framework.base.service.UserService;
import com.cnpc.framework.utils.DateUtil;
import com.cnpc.framework.utils.PropertiesUtil;
import com.cnpc.framework.utils.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;

/**
 * 附件上传控制器
 *
 * @author cnpc
 */
@Service("uploaderService")
public class UploaderServiceImpl extends BaseServiceImpl implements UploaderService {
    private final Logger logger= LoggerFactory.getLogger(getClass());
    @Resource
    private UserService userService;

    /**
     * 创建文件
     *
     * @param file
     * @return
     */
    public File createFile(MultipartFile file) {

        /*String dirPath = PropertiesUtil.getValue("uploadPath");
        return createFile(file, dirPath);*/
        return null;
    }

    public File createFile(MultipartFile file, String dirPath) {

        File dir = new File(dirPath);
        if (!dir.exists()) {
            dir.mkdir();
        }
        String filePath = dirPath + "/" + (new Date().getTime()) + "_" + file.getOriginalFilename();
        File newFile = new File(filePath);
        try {
            InputStream ins = file.getInputStream();
            OutputStream os = new FileOutputStream(newFile);
            int bytesRead = 0;
            byte[] buffer = new byte[1024];
            while ((bytesRead = ins.read(buffer, 0, 1024)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return newFile;
    }


    public String saveAvatar(String userId, String fileName, String filePath, String dirPath) {
        UserAvatar avatar = null;
        if(!StrUtil.isEmpty(userId)&&!userId.equals("0"))
                avatar=userService.getAvatarByUserId(userId);
        String avatar_id=avatar==null?null:avatar.getId();
        //图片替换
        if (avatar != null) {
            File file = new File(dirPath + avatar.getSrc());
            if (file.exists())
                file.delete();
            avatar.setName(fileName);
            avatar.setSrc(filePath);
            avatar.setUpdateDateTime(new Date());
            this.update(avatar);
        }
        // 新增图片
        else {
            avatar = new UserAvatar();
            avatar.setName(fileName);
            avatar.setSrc(filePath);
            avatar.setCreateDateTime(new Date());
            avatar.setUserId(userId);
            avatar_id=this.save(avatar).toString();
        }
        return avatar_id;
    }

    @Override
    public BaseResponse getFileList(String formId, Integer pageNum, Integer pageSize) throws Exception {
        BaseResponse response = new BaseResponse();
        String cntsql = "select count(*) from tbl_file rmd where  deleted = 0 ";
        String sql = "select f.*,DATE_FORMAT(f.create_date_time,'%Y-%m-%d %H:%i:%s') as  create_time from tbl_file f  where  deleted = 0  ";

        Map<String, Object> cntparams = new HashMap<>();
        if (StrUtil.isNotEmpty(formId)) {
            cntsql += " and form_ID = :formId ";
            sql += " and form_ID = :formId ";

            cntparams.put("formId", formId);
        }
        sql += " order by f.create_date_time DESC ";
        Long cnt = countBySql(cntsql, cntparams);

        List<Map<String, Object>> list = null;
        if (cnt > 0) {
            if (pageSize != null && pageSize > 0 && pageNum != null && pageNum > 0) {
                list = findMapBySql(sql, cntparams, pageNum, pageSize);
            } else {
                list = findMapBySql(sql, cntparams);
            }
        }


        Map<String, Object> data = new HashMap<>();
        data.put("count", cnt);
        data.put("list", list);
        response.setStatus(0);
        response.setData(data);
        return response;
    }

    @Override
    public BaseResponse deleteFile(List<String> fileIds, String basePath) throws Exception {

        String sql = "select * from tbl_file where id in ( :fileIds )";
        Map<String, Object> params = new HashMap<>();
        params.put("fileIds", fileIds);
        List<SysFile> files = findBySql(sql, params, SysFile.class);
        for (SysFile sysFile : files) {
            String filePath = sysFile.getFilePath();
            File file = new File(basePath + filePath);
            System.out.println(filePath);
            if (file.exists()) {
                file.delete();
            }
        }
        String deleteSql = "delete from tbl_file where id in ( :fileIds ) ";
        executeSql(deleteSql, params);
        BaseResponse response = new BaseResponse();
        response.setStatus(0);
        return response;
    }

    @Override
    public void deleteFiles() throws Exception {
        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
        ServletContext servletContext = webApplicationContext.getServletContext();
        String basePath = servletContext.getRealPath("/");

        String sql = "select * from tbl_file where form_ID = 'delete' ";

        List<SysFile> files = findBySql(sql, SysFile.class);
        if (files != null) {
            List<String> fileIds = new ArrayList<>();
            for (SysFile sysFile : files) {
                String filePath = sysFile.getFilePath();
                fileIds.add(sysFile.getId());

                File file = new File(basePath + filePath);
                System.out.println(filePath);
                if (file.exists()) {
                    file.delete();
                }
            }
            String deleteSql = "delete from tbl_file where id in ( :fileIds ) ";
            Map<String, Object> params = new HashMap<>();
            params.put("fileIds", fileIds);
            executeSql(deleteSql, params);
        }

    }

    @Override
    public BaseResponse upload(MultipartFile[] files, String userId, String formId, String type, String dirPath) throws IOException {
        BaseResponse baseResponse = new BaseResponse();
        String relativePath = getUploadPath(type);
        ArrayList<Integer> arr = new ArrayList<>();
        //缓存当前的文件
        List<SysFile> fileList = new ArrayList<>();

        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i];

            if (!file.isEmpty()) {
                InputStream in = null;
                OutputStream out = null;
                try {
                    File dir = new File(dirPath + relativePath);
                    if (!dir.exists())
                        dir.mkdirs();
                    //这样也可以上传同名文件了
                    String filePrefixFormat = "yyyyMMddHHmmssS";
                    System.out.println(DateUtil.format(new Date(), filePrefixFormat));
                    //String savedName = DateUtil.format(new Date(), filePrefixFormat) + "_" + file.getOriginalFilename();
                    String savedName=DateUtil.format(new Date(),filePrefixFormat)+"_" + (Math.random() * 1000000)  + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
                    String filePath = dir.getAbsolutePath() + "/" + savedName;
                    File serverFile = new File(filePath);
                    //将文件写入到服务器
                    //FileUtil.copyInputStreamToFile(file.getInputStream(),serverFile);
                    file.transferTo(serverFile);
                    SysFile sysFile = new SysFile();
                    sysFile.setFileName(file.getOriginalFilename());
                    sysFile.setSavedName(savedName);
                    sysFile.setCreateDateTime(new Date());
                    sysFile.setUpdateDateTime(new Date());
                    if (StrUtil.isNotEmpty(userId)) {
                        sysFile.setCreateUserId(userId);
                    }
                    if (StrUtil.isNotEmpty(formId)) {
                        sysFile.setFormId(formId);
                    }
                    sysFile.setDeleted(0);
                    sysFile.setType(type);
                    sysFile.setFileSize(file.getSize());
                    sysFile.setFilePath(relativePath + "/" + savedName);
                    fileList.add(sysFile);
                    /*preview.add("<div class=\"file-preview-other\">\n" +
                            "<span class=\"file-other-icon\"><i class=\"fa fa-file-o text-default\"></i></span>\n" +
                            "</div>");*/

                    logger.info("Server File Location=" + serverFile.getAbsolutePath());
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error(file.getOriginalFilename() + "上传发生异常，异常原因：" + e.getMessage());
                    arr.add(i);
                } finally {
                    if (out != null) {
                        out.close();
                    }
                    if (in != null) {
                        in.close();
                    }
                }
            } else {
                arr.add(i);
            }
        }

        if (arr.size() > 0) {

            baseResponse.setStatus(1);
            baseResponse.setMessage("文件上传失败！");
        } else {

            /*if ("ft_fp".equals(type)){
                FPRecord fpRecord = get(FPRecord.class, formId);
                fpRecord.setStatus("1");
                update(fpRecord);
                String orderId = fpRecord.getOrderId();
                String tableName ="";
                if (orderId.startsWith("SF")) {
                    tableName = "jy_pay";
                } else if (orderId.startsWith("CZ")) {
                    tableName = "jy_charge";
                } else if (orderId.startsWith("CARD")) {
                    tableName = "jy_card";
                }
                String[] orderIds = orderId.split(",");
                String sql = " update " + tableName + " set STATUS = 3 where ORDER_ID in (:orderIds) ";
                Map<String, Object> params = new HashMap<>();
                params.put("orderIds", orderIds);
                executeSql(sql,params);
                sql = " update tbl_file set deleted = 1,form_ID = null where form_ID = '"+formId+"'  ";
                executeSql(sql);
            }*/

            batchSave(fileList);
            baseResponse.setStatus(0);
            baseResponse.setData(fileList);
        }

        return baseResponse;
    }

    public String getUploadPath(String type){
        String path ;

        if ("ft_fp".equals(type)) {
            path = PropertiesUtil.getValue("invoicePath");
        }else if ("ft_image".equals(type)) {
            path = PropertiesUtil.getValue("imgPath");
        }else if ("ft_avatar".equals(type)) {
            path = PropertiesUtil.getValue("avatarPath");
        }else {
            path = PropertiesUtil.getValue("uploaderPath");
        }

        return path;
    }
}
